using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Dapper;
using MediatR;
using Microsoft.Extensions.Logging;
using RBAC.Domain.SalesManage;
using RBAC.ErrorCode;
using RBAC.Interstructrue.Base;
using RBAC.Write.Api.Application.Command.ERP.SalesManagement.Return;
using RBAC.Write.Api.Infrastructure;

namespace RBAC.Write.Api.Application.Handler.ERP.SalesManagement.Return
{
    /// <summary>
    /// 更新退货通知单处理器
    /// </summary>
    public class UpdateReturnNoticeHandler : IRequestHandler<UpdateReturnNoticeCommand, APIResult<int>>
    {
        private readonly IDbConnectionFactory _dbConnectionFactory;
        private readonly ILogger<UpdateReturnNoticeHandler> _logger;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="dbConnectionFactory">数据库连接工厂</param>
        /// <param name="logger">日志记录器</param>
        public UpdateReturnNoticeHandler(IDbConnectionFactory dbConnectionFactory, ILogger<UpdateReturnNoticeHandler> logger)
        {
            _dbConnectionFactory = dbConnectionFactory;
            _logger = logger;
        }

        /// <summary>
        /// 处理更新退货通知单请求
        /// </summary>
        /// <param name="request">更新命令</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>更新结果</returns>
        public async Task<APIResult<int>> Handle(UpdateReturnNoticeCommand request, CancellationToken cancellationToken)
        {
            IDbConnection connection = null;
            IDbTransaction transaction = null;

            try
            {
                connection = _dbConnectionFactory.CreateConnection();
                transaction = connection.BeginTransaction();

                // 1. 检查退货通知单是否存在且可编辑
                var checkSql = @"
                    SELECT BillStatus 
                    FROM ReturnNotice 
                    WHERE Id = @Id AND IsDeleted = 0";

                var currentStatus = await connection.ExecuteScalarAsync<int?>(checkSql, new { request.Id }, transaction);

                if (!currentStatus.HasValue)
                {
                    return new APIResult<int>
                    {
                        Code = APIEnums.Fail,
                        Msg = "退货通知单不存在"
                    };
                }

                if (currentStatus == 1) // 已审核状态
                {
                    return new APIResult<int>
                    {
                        Code = APIEnums.Error,
                        Msg = "已审核的单据不能修改"
                    };
                }

                // 2. 更新退货通知单主表
                var updateMainSql = @"
                    UPDATE ReturnNotice 
                    SET 
                        BillCode = @BillCode,
                        BillDate = @BillDate,
                        BusinessType = @BusinessType,
                        CustomerName = @CustomerName,
                        Operator = @Operator,
                        BusinessStatus = @BusinessStatus,
                        Remark = @Remark,
                        UpdateTime = GETDATE()
                    WHERE Id = @Id";

                var affectedRows = await connection.ExecuteAsync(updateMainSql, new
                {
                    request.Id,
                    request.BillCode,
                    request.BillDate,
                    request.BusinessType,
                    request.CustomerName,
                    request.Operator,
                    request.BusinessStatus,
                    request.Remark
                }, transaction);

                if (affectedRows == 0)
                {
                    transaction.Rollback();
                    return new APIResult<int>
                    {
                        Code = APIEnums.Error,
                        Msg = "更新失败"
                    };
                }

                // 3. 删除原有明细
                var deleteItemsSql = @"DELETE FROM ReturnMaterials WHERE ReturnNoticeId = @ReturnNoticeId";
                await connection.ExecuteAsync(deleteItemsSql, new { ReturnNoticeId = request.Id }, transaction);

                // 4. 插入新明细
                if (request.Items != null && request.Items.Any())
                {
                    var insertItemsSql = @"
                        INSERT INTO ReturnMaterials (
                            ReturnNoticeId, MaterialCode, MaterialName, Specification, 
                            Unit, ReturnQuantity, BatchNumber, Remark, CreateTime, UpdateTime
                        ) VALUES (
                            @ReturnNoticeId, @MaterialCode, @MaterialName, @Specification,
                            @Unit, @ReturnQuantity, @BatchNumber, @Remark, GETDATE(), GETDATE()
                        )";

                    var itemsToInsert = request.Items.Select(item => new
                    {
                        ReturnNoticeId = request.Id,
                        item.MaterialCode,
                        item.MaterialName,
                        item.Specification,
                        item.Unit,
                        item.ReturnQuantity,
                        item.BatchNumber,
                        item.Remark
                    });

                    await connection.ExecuteAsync(insertItemsSql, itemsToInsert, transaction);
                }

                transaction.Commit();

                return new APIResult<int>
                {
                    Code = APIEnums.Success,
                    Msg = "更新成功",
                    Data = affectedRows
                };
            }
            catch (Exception ex)
            {
                transaction?.Rollback();
                _logger.LogError(ex, "更新退货通知单失败");
                return new APIResult<int>
                {
                    Code = APIEnums.Error,
                    Msg = $"更新失败：{ex.Message}"
                };
            }
            finally
            {
                transaction?.Dispose();
                connection?.Dispose();
            }
        }
    }
}